﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Koopakiller.Numerics.Resources;

namespace System
{
    /// <summary>
    /// Contains extensions for the <see cref="System"/> namespace.
    /// </summary>
    public static class Extensions_System
    {
        /// <summary>
        /// Split an array at a defined length an begin a new line to create a 2D array.
        /// </summary>
        /// <typeparam name="T">The type of the elements of <paramref name="array"/></typeparam>
        /// <param name="array">The array to split.</param>
        /// <param name="stride">The length of one line.</param>
        /// <returns>A 2D array with <paramref name="stride"/> columns and fitting rows.</returns>
        public static T[,] To2D<T>(this T[] array, int stride)
        {
            if (array == null)
                throw ExceptionHelper.GetArgumentNull("array", "extension", null);
            if (stride < 0)
                throw ExceptionHelper.GetArgumentOutOfRange("stride", "minval", "0");
            if (array.Length % stride != 0)
                throw ExceptionHelper.GetArgumentOutOfRange("array", "mustdivider", "stride (" + stride + ")", "array.Length (" + array.Length + ")");

            T[,] result = new T[stride, array.Length / stride];
            for (int i = 0; i < result.Length / stride; ++i)
            {
                for (int x = 0; x < stride; ++x)
                    result[x, i] = array[stride * (i) + x];
            }
            return result;
        }
        /// <summary>
        /// Split an array at a defined length an begin a new line to create a jagged 2D array.
        /// </summary>
        /// <typeparam name="T">The type of the elements of <paramref name="array"/></typeparam>
        /// <param name="array">The array to split.</param>
        /// <param name="stride">The length of one line.</param>
        /// <returns>A 2D array with <paramref name="stride"/> elements in each row and fitting rows.</returns>
        public static T[][] ToJagged2D<T>(this T[] array, int stride)
        {
            if (array == null)
                throw ExceptionHelper.GetArgumentNull("array", "extension", null);
            if (stride < 0)
                throw ExceptionHelper.GetArgumentOutOfRange("stride", "minval", "0");
            if (array.Length % stride != 0)
                throw ExceptionHelper.GetArgumentOutOfRange("array", "mustdivider", "stride (" + stride + ")", "array.Length (" + array.Length + ")");

            T[][] result = new T[stride][];
            for (int i = 0; i < result.Length; ++i)
            {
                result[i] = new T[array.Length / stride];
                for (int y = 0; y < result[i].Length; ++y)
                    result[i][y] = array[stride * y + i];
            }
            return result;
        }
    }
}
